package cn.ibizlab.util.service;

import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.domain.AuditItem;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.helper.BeanCache;
import cn.ibizlab.util.security.AuthenticationUser;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 实体[DataAudit] 服务对象接口
 */
public interface IBZDataAuditService {
    void createAudit(HttpServletRequest request, EntityBase entity, Object idValue);
    void updateAudit(HttpServletRequest request, EntityBase beforeEntity, EntityBase entity, Object idValue);
    void removeAudit(HttpServletRequest request, EntityBase entity, Object idValue);

    void customAudit(String caller,String method,Object idValue,EntityBase entity,String name,HttpServletRequest request);

    default List<AuditItem> getAuditInfo(EntityBase entity) {
        return getAuditInfo(entity,BeanCache.get(entity.getClass()).getAudits());
    }
    default List<AuditItem> getAuditInfo(EntityBase entity,List<BeanCache.FieldItem> audits) {
        List<AuditItem> auditFieldArray = new ArrayList<>();
        audits.forEach(item->{
            String fieldName = item.getCodeName();
            DEField deField = item.getDeField();
            Object value = dataTransfer(entity.get(fieldName),item.getFormat());
            if(!ObjectUtils.isEmpty(value)) {
                AuditItem auditFieldObj = new AuditItem();
                auditFieldObj.setId(item.getJsonName());
                auditFieldObj.setLabel(item.getLogicName());
                auditFieldObj.setValue(value);
                if(!ObjectUtils.isEmpty(deField)&&!ObjectUtils.isEmpty(deField.dict())) {
                    auditFieldObj.setDict(deField.dict());
                }
                auditFieldArray.add(auditFieldObj);
            }
        });
        return auditFieldArray;
    }

    default List<AuditItem> getUpdateAuditInfo(EntityBase oldData, EntityBase newData){
        return getUpdateAuditInfo(oldData,newData,BeanCache.get(oldData.getClass()).getAudits());
    }

    default List<AuditItem> getUpdateAuditInfo(EntityBase oldData, EntityBase newData,List<BeanCache.FieldItem> audits){
        List<AuditItem> auditFieldArray = new ArrayList<>();
        audits.forEach(item->{
            String fieldName = item.getCodeName();
            DEField deField = item.getDeField();
            Object oldValue = oldData.get(fieldName);//老属性值
            Object newValue = newData.get(fieldName);//新属性值
            if(!compare(oldValue, newValue)) {


                AuditItem auditFieldObj = new AuditItem();
                auditFieldObj.setId(item.getJsonName());
                auditFieldObj.setLabel(item.getLogicName());
                auditFieldObj.setValue(dataTransfer(newValue, deField.format()));
                auditFieldObj.setBefore(dataTransfer(oldValue, deField.format()));

                if(!ObjectUtils.isEmpty(deField)&&!ObjectUtils.isEmpty(deField.dict())) {
                    auditFieldObj.setDict(deField.dict());
                }
                auditFieldArray.add(auditFieldObj);
            }
        });
        return auditFieldArray;
    }

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    default Object dataTransfer(Object value, String strFormat) {
        if(value==null) {
            return "";
        }
        Object transResult=value;
        if(value instanceof Date) {  //时间类型转换
            Date timestamp = (Date)value;
            transResult = sdf.format(timestamp);
        }
        else if((!ObjectUtils.isEmpty(strFormat))) {
            transResult =  String.format(strFormat,transResult);
        }
        return transResult;
    }

    /**
     * 对象比较
     * @param sourceObj 比较源对象
     * @param targetObj 比较目标对象
     * @return
     */
    default boolean compare(Object sourceObj, Object targetObj) {
        if(sourceObj == null && targetObj == null) {
            return true;
        }
        if(sourceObj == null && targetObj != null) {
            return false;
        }
        return sourceObj.equals(targetObj);
    }


    /**
     * 获取Ip地址
     * @param request
     * @return
     */
    default String getIpAddress(HttpServletRequest request, AuthenticationUser authenticationUser) {
        //客户端有提交ip，以提交的ip为准
        if(authenticationUser != null && !ObjectUtils.isEmpty(authenticationUser.getClientIp())) {
            return authenticationUser.getClientIp();
        }
        if(request == null) {
            return "";
        }
        String xIp = request.getHeader("X-Real-IP");
        String xFor = request.getHeader("X-Forwarded-For");
        if(!ObjectUtils.isEmpty(xFor) && !"unKnown".equalsIgnoreCase(xFor)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = xFor.indexOf(",");
            if(index != -1){
                return xFor.substring(0,index);
            }else{
                return xFor;
            }
        }
        xFor = xIp;
        if(!ObjectUtils.isEmpty(xFor) && !"unKnown".equalsIgnoreCase(xFor)) {
            return xFor;
        }
        if (ObjectUtils.isEmpty(xFor) || "unknown".equalsIgnoreCase(xFor)) {
            xFor = request.getHeader("Proxy-Client-IP");
        }
        if (ObjectUtils.isEmpty(xFor) || "unknown".equalsIgnoreCase(xFor)) {
            xFor = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ObjectUtils.isEmpty(xFor) || "unknown".equalsIgnoreCase(xFor)) {
            xFor = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ObjectUtils.isEmpty(xFor) || "unknown".equalsIgnoreCase(xFor)) {
            xFor = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ObjectUtils.isEmpty(xFor) || "unknown".equalsIgnoreCase(xFor)) {
            xFor = request.getRemoteAddr();
        }
        return xFor;
    }
}